package servlet;

import bean.User;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import service.BicycleService;
import util.JsonWrapperBuilder;
import util.ResponseUtil;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.sql.SQLException;

/**
 * 自行车管理
 *
 * @author liu
 */
@WebServlet(name = "bicycle", urlPatterns = {"/bikes", "/locks"})
public class BicycleServlet extends HttpServlet {

    private BicycleService bicycleService = new BicycleService();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        if ("/bikes".equalsIgnoreCase(req.getRequestURI())) {
            JSONObject jsonObject = bikes(req, resp);
            ResponseUtil.write(resp, jsonObject);
        } else {
            String lockId = req.getParameter("lid");
            if (isLockValid(lockId)) {
                ResponseUtil.write(resp, 200, "valid lock");
            } else {
                ResponseUtil.write(resp, 301, "invalid lock");
            }
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        JSONObject jsonObject = bikeAdd(req, resp);
        ResponseUtil.write(resp, jsonObject);
    }

    @Override
    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        JSONObject jsonObject = bikeModify(req);
        ResponseUtil.write(resp, jsonObject);
    }

    @Override
    protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        JSONObject jsonObject = bikeDelete(req);
        ResponseUtil.write(resp, jsonObject);
    }

    //get请求
    private JSONObject bikes(HttpServletRequest request, HttpServletResponse response) {
        if (allNotNull(request.getParameter("start"), request.getParameter("pagesize"))) {
            int start = Integer.parseInt(request.getParameter("start"));
            int pagesize = Integer.parseInt(request.getParameter("pagesize"));
            return bicycleService.bikesPagination(start, pagesize);
        } else if (allNotNull(request.getParameter("type"), request.getParameter("value"))) {
            return bicycleService.bikesQuery(request.getParameter("type"), request.getParameter("value"));
        } else if (allNotNull(request.getParameter("type"), request.getParameter("prefix"))) {
            return bicycleService.bikeDynamicQuery(request.getParameter("type"), request.getParameter("prefix"));
        } else if (allNotNull(request.getParameter("myLocationX"), request.getParameter("myLocationY"))) {
            return bicycleService.bikeNearby(request.getParameter("myLocationX"), request.getParameter("myLocationY"));
        } else {
            return bicycleService.bikeTotal();
        }
    }

    //post请求
    private JSONObject bikeAdd(HttpServletRequest request, HttpServletResponse response) {

        JSONObject data = JSONObject.fromObject(readJSONString(request));
        int role = (Integer) data.get("role");
        boolean canUse = data.getBoolean("canUse");
        String imagePath = data.getString("imagePath");
        String username = null;
        String lockId = null;
        JSONArray values = null;
        if (role == 1) {
            JSONObject value = data.getJSONObject("value");
            username = value.getString("username");
            lockId = value.getString("lockId");
            int userId = bicycleService.getUserId(username);
            if (userId == -1) {
                return new JsonWrapperBuilder()
                    .setStatus(304)
                    .setMsg("failed").build();
            }
            bicycleService.addBicycle(userId, lockId, imagePath, canUse ? 1 : 0);
        } else if (role == -1) {
            JSONObject value = data.getJSONObject("value");
            String phone = value.getString("phone");
            String name = (String) value.get("name");
            lockId = value.getString("lockId");
            User user = new User();
            user.setPhone(phone);
            user.setName(name);
            user.setBalance("0");
            user.setScore("0");
            user.setStatus("1");
            user.setPassword(phone.substring(phone.length() - 6, phone.length()));
            user.setUserName(phone);
            int userId;
            userId = bicycleService.addUser(user);
            if (userId == -1) {
                return new JsonWrapperBuilder()
                    .setStatus(304)
                    .setMsg("failed").build();
            }

            bicycleService.addBicycle(userId, lockId, imagePath, canUse ? 1 : 0);
        } else {
            // there should use default image path.
            values = data.getJSONArray("values");
            for (Object value : values) {
                bicycleService.addBicycle(1, ((JSONObject) value).getString("lockId"), imagePath, canUse ? 1 : 0);
            }
        }
        JsonWrapperBuilder builder = new JsonWrapperBuilder().setStatus(200).setMsg("success");
        return allNotNull(username, lockId) ?
            builder.setDataEntry("username", username).setDataEntry("lockId", lockId).build()
            : builder.setDataJsonArray("values", values).build();
    }

    //put请求
    private JSONObject bikeModify(HttpServletRequest req) {
        String paramStr = readJSONString(req);
        JSONObject paramJson = JSONObject.fromObject(paramStr).getJSONObject("params");
        Integer id = paramJson.getInt("id");
        Integer lockId = paramJson.getInt("lockId");
        Integer status = paramJson.getInt("status");
        JSONObject bikeJson;
        if (bicycleService.updateById(id, lockId, status)) {
            bikeJson = bicycleService.bikesQuery("id", String.valueOf(id));
        } else {
            bikeJson = failedJSON();
        }
        return bikeJson;
    }

    //delete请求
    private JSONObject bikeDelete(HttpServletRequest req) {
        String id = req.getParameter("id");
        if (bicycleService.delete(id)) {
            return successEmptyJSON();
        } else {
            return failedJSON();
        }
    }

    private JSONObject successEmptyJSON() {
        return new JsonWrapperBuilder()
            .setStatus(200)
            .setMsg("success").build();
    }

    private JSONObject failedJSON() {
        return new JsonWrapperBuilder()
            .setStatus(304)
            .setMsg("failed").build();
    }

    private boolean allNotNull(Object... objects) {
        boolean result = true;
        for (Object object : objects) {
            result = result && (object != null);
        }
        return result;
    }

    private boolean isLockValid(String lockId) {
        if (lockId == null) {
            return false;
        }
        try {
            return bicycleService.isLockValid(lockId);
        } catch (SQLException e) {
            e.printStackTrace();
            return false;
        }
    }

    private String readJSONString(HttpServletRequest request) {
        StringBuilder json = new StringBuilder();
        String line;
        try {
            BufferedReader reader = request.getReader();
            while ((line = reader.readLine()) != null) {
                json.append(line);
            }
        } catch (Exception e) {
            System.out.println(e.toString());
        }
        return json.toString();
    }
}
